using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Design;
using Camalon.Drawing;

namespace Camalon.Drawing.Design
{
	public class ShapePenEditor:UITypeEditor
	{
        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
        {
            return UITypeEditorEditStyle.None;
        }


		public override bool GetPaintValueSupported(ITypeDescriptorContext context) 
		{
			return true;
		}

		
		public override void PaintValue(PaintValueEventArgs pe) 
		{
			
			if(pe.Value == null || !( pe.Value is ShapePen) ) 
			{
				base.PaintValue( pe);
				return;
			}

			try
			{

				

				ShapePen shapePen = pe.Value as ShapePen;
				if( shapePen.Fill == null && !shapePen.Color.IsVisible) 
				{base.PaintValue( pe); return;}
				
				ShapeFill shapeFill = shapePen.Fill;

				

				float penWidth = 2f;
				Rectangle b = pe.Bounds;
				b.Inflate( -3, -3);
				b.Width -=2;b.Height-=2;
				
				Pen pen = GetPen( shapePen, b, penWidth);

				if( pen == null) {base.PaintValue( pe); return;}
		

				pe.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
				Point p1 = b.Location;
				Point p2 = new Point( b.Right, b.Bottom);
				Point[] pts = new Point[]{p1,p2};
				pe.Graphics.DrawLines(pen, pts);

//				string name = TypeDescriptor.GetComponentName( pe.Value );
//				SizeF size = pe.Graphics.MeasureString( name, System.Windows.Forms.Form.DefaultFont );
//				Rectangle bigrect = pe.Bounds;
//				bigrect.X+=bigrect.Width + (int)size.Width + 20;
//				Point ttb1 = new Point(bigrect.X, bigrect.Top + bigrect.Height/2);
//				Point ttb2 = new Point(bigrect.Right, bigrect.Top + bigrect.Height/2);
//				pe.Graphics.DrawLine(pen, ttb1, ttb2);

				
				
				pe.Graphics.SmoothingMode = SmoothingMode.Default;
			

				pen.Dispose();pen = null;
				//brush.Dispose();brush = null;

			}
			catch( Exception e )
			{
				FileWatcher.WriteLine("ShapeFillEditor::PaintValue failed:"+ e.Message +"\n"+e.StackTrace);
				throw e;
			}

		}

		public static Pen GetPen( ShapePen shapePen, Rectangle bounds, float penWidth )
		{
			if( shapePen == null) return null;
			if( shapePen.Fill == null && !shapePen.Color.IsVisible) return null;

			ShapeFill shapeFill = shapePen.Fill;

			Rectangle b = bounds;
			Brush brush = null;

			if( shapeFill == null) brush = new SolidBrush( shapePen.Color);
			else switch( shapeFill.FillType)
				 {
					 case FillType.Hatched:
					 {
						 brush = ((HatchFill)shapeFill).GetBrush();
						 break;
					 }
					 case FillType.LinearGradient:
					 {
						 brush =((LinearGradientFill) shapeFill).GetBrush( b );
						 break;
					 }
					 case FillType.PathGradient:
					 {
						 break;
					 }
					 case FillType.Solid:
					 {
						 brush =((SolidFill) shapeFill).GetBrush();
						 break;
					 }
					 case FillType.Texture:
					 {
						 brush = ((TextureFill)shapeFill).GetBrush();
						 break;
					 }
				 }

			Pen pen = new Pen( brush, penWidth );

			//pen.Alignment		= shapePen.Inset ? PenAlignment.Inset: PenAlignment.Center;//shapePen.Alignment;
			pen.Alignment		= PenAlignment.Center;

			int[] compoundArray = shapePen.Compounds;
			if( compoundArray.Length > 1 ) 
			{
				float[] compounds = new float[compoundArray.Length];
				for (int i = 0; i < compounds .Length; i++) compounds[i] = ((float)compoundArray[i])/100f;
				pen.CompoundArray	= compounds;
			}
				
			pen.DashCap			= shapePen.DashCap;
			pen.DashOffset		= shapePen.ValidateDashOffsetGDI( penWidth);// shapePen.DashOffset;

			if( shapePen.DashStyle == DashStyle.Custom  ) 
			{	
				float[] dashValues = shapePen.ValidateDashPatternGDI(penWidth);// ShapePen.ValidateDashPatternGDI( shapePen.DashPattern , penWidth);
				if( dashValues != null) pen.DashPattern		= dashValues;
				else pen.DashStyle = DashStyle.Solid;
			}
			else pen.DashStyle		= shapePen.DashStyle;

			pen.LineJoin		= shapePen.LineJoin;
			pen.MiterLimit		= shapePen.MiterLimit;

			//shapePen.MakeCap( pen );

			brush.Dispose(); brush = null;
			return pen;
		}

	}
}
